package com.the_ring.chapter12.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Scroller;

import androidx.annotation.Nullable;

import com.the_ring.chapter12.R;

public class ScrollLayout extends LinearLayout {

    private Scroller scroller;
    private PointF originPos;
    private int lastMargin = 0;
    private ImageView sceneIv;
    private Bitmap bitmap;
    private boolean isScrolling = false;

    public ScrollLayout(Context context) {
        this(context, null);
    }

    public ScrollLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        // 创建一个基于线性插值器的滚动器对象
        scroller = new Scroller(context, new LinearInterpolator());
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.gift01);
        ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        sceneIv = new ImageView(context);
        sceneIv.setLayoutParams(params);
        sceneIv.setImageBitmap(bitmap);
        addView(sceneIv);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!scroller.isFinished() && isScrolling) {
            // 正在滚动则忽略触摸事件
            return super.onTouchEvent(event);
        }
        PointF nowPos = new PointF(event.getX(), event.getY());
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            originPos = new PointF(event.getX(), event.getY());
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            // 把视图从起点移动到终点
            moveView(originPos, nowPos);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            // 需要继续滚动
            if (moveView(originPos, nowPos)) {
                isScrolling = true;
                // 判断滚动方向，并发出滚动命令
                judgeScroll(originPos, nowPos);
            }
        }
        return true;
    }

    // 把视图从起点移动到终点
    private boolean moveView(PointF lastPos, PointF thisPos) {
        int offsetX = (int) (thisPos.x - lastPos.x);
        LinearLayout.LayoutParams params = (LayoutParams) sceneIv.getLayoutParams();
        params.leftMargin = lastMargin + offsetX;
        params.rightMargin = -lastMargin - offsetX;
        if (Math.abs(params.leftMargin) < sceneIv.getMeasuredWidth()) {
            // 还没滚到底，继续滚动
            sceneIv.setLayoutParams(params);
            sceneIv.postInvalidate();
            return true;
        } else {
            // 已经滚到底，持续滚动
            return false;
        }
    }

    private void judgeScroll(PointF lastPos, PointF thisPos) {
        int offsetX = (int) (thisPos.x - lastPos.x);
        if (Math.abs(offsetX) < sceneIv.getMeasuredWidth() / 2) {
            // 滚回原处
            scroller.startScroll(offsetX, 0, -offsetX, 0, 1000);
        } else if (offsetX >= sceneIv.getMeasuredWidth() / 2) {
            // 滚到右边
            scroller.startScroll(offsetX, 0, sceneIv.getMeasuredWidth() - offsetX, 0, 1000);
        } else if (offsetX <= -sceneIv.getMeasuredWidth() / 2) {
            // 滚到左边
            scroller.startScroll(offsetX, 0, -sceneIv.getMeasuredWidth() - offsetX, 0, 1000);
        }
    }

    // 在滚动器过程中不断触发，用于计算当前的视图偏移位置
    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset() && isScrolling) {
            // 尚未滚动完毕
            LinearLayout.LayoutParams params = (LayoutParams) sceneIv.getLayoutParams();
            params.leftMargin = lastMargin + scroller.getCurrX();
            params.rightMargin = -lastMargin - scroller.getCurrX();
            sceneIv.setLayoutParams(params);
            if (scroller.getFinalX() == scroller.getCurrX()) {
                // 滚到终点
                isScrolling = false;
                lastMargin = params.leftMargin;
            }
        }
    }
}
